<script setup lang="ts">
import type{ stateOption,SelectOption ,SelectProps,SelectionEmits} from './type';
import Tooltip from '../Tooltip/Tooltip.vue'; 
import Input from '../Input/Input.vue'; 
import Icon from '../Icon/Icon.vue';
import { isFunction } from 'lodash-es';

import { computed, reactive, ref ,watch,type Ref} from 'vue';
import type{ TooltipInstance } from '../Tooltip/type';
import type{ InputInstance } from '../Input/type';
defineOptions({
  name:'WfSelect',
})

function findOption (value:string){
  const option = props.options.find((item)=>item.value === value)
  return option;
}

const emits = defineEmits<SelectionEmits>();
const props = withDefaults(defineProps<SelectProps>(),{
  options:()=>[],
  disabled:false,
});

const initOption = findOption(props.modelValue)
const states = reactive<stateOption>({
  curInput:initOption ? initOption.label : '',
  curOption:initOption!,
  mouseHover:false,
  loading:false,
})

const filteredOptions = ref(props.options)
watch(()=>props.options,(newOptions)=>{
  filteredOptions.value = newOptions
})
// 过滤生成对应的 options
const generateFilterOptions = async (searchValue:string)=>{
  if(!props.filterable)return 
  if(props.filterMethod && isFunction(props.filterMethod)){
    filteredOptions.value = props.filterMethod(searchValue)
  }else if(props.remote && props.remoteMethod && isFunction(props.remoteMethod)){
    states.loading = true
    try{
      filteredOptions.value = await props.remoteMethod(searchValue)
    }catch (e){
      console.log(e)
      filteredOptions.value = []
    }finally{
      states.loading = false;
    }
  }else{
    filteredOptions.value = props.options.filter((option)=>option.label.includes(searchValue))
  }
}
// 过滤事件
const onFilter = ()=>{
  generateFilterOptions(states.curInput)
}

// 过滤后的 placeholder
const filteredPlaceholder = computed(()=>{
  // 是过滤模式 之前有过选项 是展开的时候
  return (props.filterable && states.curOption && isSelectOpen.value)
  ? states.curOption.label : props.placeholder
})


const inputRef = ref() as Ref<InputInstance>
// 需要手动控制 tooltip 的打开和关闭 ，需要拿到tooltip的 组价实例
const tooltipRef = ref() as Ref<TooltipInstance>
const isSelectOpen = ref(false)
const controlSelect = (value:boolean)=>{
  if(props.disabled)return 
  // 允许用的情况下
  if(value){
    // filte 模式
    // 之前选择过对应的值
    if(props.filterable && states.curOption){
      states.curInput = ''
    }
    // 进行一次默认选项的生成
    // 注意上面一个if 语句 已经将 curInput 设置为 空了
    if(props.filterable){
      generateFilterOptions(states.curInput)
    }
    tooltipRef.value.show()
  }
  else{
    tooltipRef.value.hide();
    // blur 时 将之前的值回灌到 input 中
    if(props.filterable){
      states.curInput = states.curOption ? states.curOption.label : '' 
    }
  } 
  isSelectOpen.value = value;
  emits('visible-change',value);
}
const controlWatch = ()=>{
  if(props.disabled)return 
  // 允许用的情况下
  if(isSelectOpen.value)controlSelect(false);
  else controlSelect(true);
}
// select 事件
const handleChange = (e:SelectOption)=>{
  if(props.disabled)return 
  // 允许用的情况下
  states.curInput = e.label
  states.curOption = e
  console.log('curInput:',states.curInput)
  emits('update:modelValue',e.value)
  emits('change',e.value)
  controlSelect(false);
  // 关闭之后 input 进行 聚焦
  inputRef.value.ref.focus()
}

const handleClear = ()=>{
  states.curInput = ''
  states.curOption = null
  emits('change','')
  emits('update:modelValue','')
  emits('clearInput')
}

// 判断是否清空
const isShowClearIcon = computed(()=>{
  // 是否可清空
  // 是否悬停
  // input 里面是否有值
  return props.clearable && states.mouseHover && states.curInput
})

const NOOP = ()=>{}


</script>
<template>
  <div
  @click="controlWatch"
  class="wf-select"
  :class="{
    'is-disabled':disabled
  }" 
  >
    <Tooltip
    ref="tooltipRef"
    placement="bottom-start"
    manual
    @click-outside="controlSelect(false)"
    >
      <Input 
      ref="inputRef"
      :readonly="!filterable || !isSelectOpen"
      @input="onFilter"
      type="text"
      v-model="states.curInput"
      :placeholder="filteredPlaceholder"
      :disabled="disabled"
      @mouseenter="states.mouseHover=true"
      @mouseleave="states.mouseHover=false"
      >
        <template #suffix>
          <!-- 清楚图标 -->
          <Icon 
          icon="circle-xmark"
          v-if="isShowClearIcon"
          class="wf-input__clear"
          @mousedown="NOOP"
          @click="handleClear"
          />

          <Icon 
          icon="angle-down" 
          v-else
          class="header-angle" 
          :class="{'is-active':isSelectOpen}"
          />
        </template>
      </Input>
      <template #content>
        <!-- 加载效果 -->
        <div v-if="states.loading" class="wf-select__loading"></div>
        <ul class="wf-select__menu">
          <template v-for="(item,index) in filteredOptions" :key="item.value">
            <li
            class="wf-select__menu-item"
            :class="{
              'is-disabled':item.disabled,
              'is-selected':states.curOption?.value===item.value
              }"
            :id="item.value"
            @click.stop="handleChange(item)"
            >
              {{ item.label }}
            </li>
          </template>
        </ul>
      </template>
    </Tooltip>
  </div>
</template>